//
//  BtnView.m
//  手势解锁2
//
//  Created by 伍银荣 on 2021/7/8.
//  Copyright © 2021 com.WYR. All rights reserved.
//

/**
 手势解锁的步骤:
 1.创建view
 2.九宫格创建的按钮
 3.将按钮与用户的交互取消,使用touchBegin方法实现按钮的触摸
 4.
 
 */



#import "BtnView.h"

@interface BtnView ()
//按钮的数据
@property (nonatomic, strong) NSMutableArray *btnArr;
//画线的数组
@property (nonatomic, strong) NSMutableArray *lineBtnArr;

@property (nonatomic, assign) CGPoint currentPoint;

@end

#define kButtonCount 9

@implementation BtnView

-(NSMutableArray *)lineBtnArr {
    if (!_lineBtnArr) {
        _lineBtnArr = [NSMutableArray array];
    }
    return _lineBtnArr;
}

//懒加载
-(NSMutableArray *)btnArr {
    if (!_btnArr) {
        _btnArr = [NSMutableArray array];
        //创建9个按钮
        for (int i = 0; i < kButtonCount; i++) {
            //创建按钮
            UIButton *btn = [[UIButton alloc]init];
            //设置密码
            btn.tag = i;
            //设置按钮的背景色
            //btn.backgroundColor = [UIColor redColor];
            //设置按钮默认状态下的图片
            [btn setImage:[UIImage imageNamed:@"yuan_nomal"] forState:UIControlStateNormal];
            //因为按钮默认点击会有灰色的图片显示出来,所以取消按钮与用户的交互
            btn.userInteractionEnabled = NO;
            //设置按钮高亮(被选中)状态下的图片
            [btn setImage:[UIImage imageNamed:@"double-circle"] forState:UIControlStateSelected];
            //设置按钮为不可用状态
            [btn setImage:[UIImage imageNamed:@"double-circle - disable"] forState:UIControlStateDisabled];
            //添加按钮
            [self addSubview:btn];
            //将按钮添加到数组中
            [self.btnArr addObject:btn];
        }
    }
    return _btnArr;
}


//手指在这个view上开始移动的时候调用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //获取触摸对象
    UITouch *t = touches.anyObject;
    //获取当前手指的位置
    CGPoint currentPoint = [t locationInView:t.view];
    for (int i = 0; i < self.btnArr.count; i++) {
        //遍历数组获取按钮
        UIButton *btn = self.btnArr[i];
        //判断当前手指的位置是否在某个按钮的范围之内
        if (CGRectContainsPoint(btn.frame, currentPoint)) {
            //就当当前这个按钮的状态设置为被选中状态(高亮状态)
            btn.selected = YES;
            [self.lineBtnArr addObject:btn];
        }
    }
}

//手指在这个view上移动的时候调用
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //获取触摸对象
    UITouch *t = touches.anyObject;
    //获取当前手指的位置
    CGPoint currentPoint = [t locationInView:t.view];
    _currentPoint = currentPoint;
    for (int i = 0; i < self.btnArr.count; i++) {
        //遍历数组获取按钮
        UIButton *btn = self.btnArr[i];
       //判断当前手指的位置是否在某个按钮的范围之内
        if (CGRectContainsPoint(btn.frame, currentPoint)) {
            //设置按钮的状态为高亮状态
            btn.selected = YES;
            //如果画线数组中没有当前手指触摸的这个按钮,就添加,反之就不再添加(解决已经触摸的按钮还能重新连线)
            if (![self.lineBtnArr containsObject:btn]) {
                [self.lineBtnArr addObject:btn];
            }
        }
    }
    //重绘
    [self setNeedsDisplay];
}


- (void)getLineBtnWithBOOL:(BOOL)status {
    for (int i = 0; i < self.lineBtnArr.count; i++) {
        //遍历连线数组获取按钮
        UIButton *btn = self.lineBtnArr[i];
        //将按钮设置为不选中状态
        btn.selected = status;
        //将按钮设置为不可用状态
        btn.enabled = status;
    }
}

//手指离开这个view的时候调用
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //将最后触摸连线的按钮中心赋值给当前手指的位置,解决撒手后最后绘制的一根线还在当前手指的位置
    _currentPoint = [[self.lineBtnArr lastObject] center];
    //重绘
    [self setNeedsDisplay];
    NSString *password = @"";
    for (int i = 0; i < self.lineBtnArr.count; i++) {
        //遍历连线数组获取按钮
        UIButton *btn = self.lineBtnArr[i];
//        //将按钮设置为不选中状态
//        btn.selected = NO;
//        //将按钮设置为不可用状态
//        btn.enabled = NO;
        password = [password stringByAppendingString:[NSString stringWithFormat:@"%ld",btn.tag]];
    }
    
    
    BOOL res = [password isEqualToString:@"012"];
    if (self.passwordBlock) {
        [self getLineBtnWithBOOL:res];
        self.passwordBlock(res);
    }
    //撒手后取消用户交互
    self.userInteractionEnabled = NO;
    //3秒后清空
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //清空
        [self clear];
        //清空之后要恢复与用户的交互
        self.userInteractionEnabled = YES;
    });
}

//清空所有按钮的状态(将所有的按钮恢复到初始状态)
- (void)clear {
    for (int i = 0; i < self.btnArr.count; i++) {
        UIButton *btn = self.btnArr[i];
        //设置按钮的状态为没有选中的状态
        btn.selected = NO;
        //设置按钮为可用状态
        btn.enabled = YES;
        //清空连接的线条
        [self.lineBtnArr removeAllObjects];
        //清空完还需要重绘
        [self setNeedsDisplay];
    }
}


//从xib文件中加载会执行这个方法(如果需要再手动绘制内容,这个方法则不适合创建btn了)
-(void)awakeFromNib {
    [super awakeFromNib];
    
}

//添加view的话会执行这个方法,还有改变view的frame也会执行这个方法
-(void)layoutSubviews {
    for (int i = 0; i < self.btnArr.count; i++) {
        //设置一列按钮的个数
        int colunm = 3;
        //按钮的宽
        CGFloat btnWidth = 74;
        //按钮的高
        CGFloat btnHeight = btnWidth;
        //按钮的间隙
        CGFloat margin = (self.frame.size.width - btnWidth * colunm) / (colunm + 1);
        //按钮的x
        CGFloat btnX = margin + (margin + btnWidth) * (i % colunm);
        //按钮的y
        CGFloat btnY = margin + (margin + btnHeight) * (i / colunm);
        //按钮的frame
        [_btnArr[i] setFrame:CGRectMake(btnX, btnY, btnWidth, btnHeight)];
    }
}



//绘制两个按钮间的线条
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    //如果当前连线按钮没有,就不执行后面的内容
    if (!self.lineBtnArr.count) {
        return;
    }
    //创建路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    for (int i = 0; i < self.lineBtnArr.count; i++) {
        //遍历画线数组获取画线的按钮
        UIButton *lineBtn = self.lineBtnArr[i];
        if (i == 0) {
            //如果是第一个按钮的,就开始绘制
            [path moveToPoint:lineBtn.center];
        } else {
            [path addLineToPoint:lineBtn.center];
        }
    }
    //添加超出按钮中心的那条线
    [path addLineToPoint:_currentPoint];
    //设置线宽
    [path setLineWidth:10];
    //设置颜色
    [[UIColor whiteColor] set];
    //设置头尾处样式
    [path setLineCapStyle:kCGLineCapRound];
    //设置连接处样式
    [path setLineJoinStyle:kCGLineJoinRound];
    //渲染
    [path stroke];
}


@end
